#include "bms_monitor.h"
#include "rtthread.h"

#define DBG_TAG "monitor"
#define DBG_LVL DBG_LOG
#include "rtdbg.h"

BMS_MonitorDataTypeDef BMS_MonitorData;

#define MONITOR_TASK_STACK_SIZE	512
#define MONITOR_TASK_PRIORITY	19
#define MONITOR_TASK_TIMESLICE	25
#define MONITOR_TASK_PERIOD		250

#define UPDATE_CELL_VOLTAGE_CYCLE	250
#define UPDAYE_BAT_VOLTAGE_CYCLE	250
#define UPDATE_CELL_TEMP_CYCLE		2000
#define UPDATE_BAT_CURRENT_CYCLE	1000

static uint16_t CountCellVoltage = 0;
static uint16_t CountBatVoltage = 0;
static uint16_t CountCellTemp = 0;
static uint16_t CountBatCurrent = 0;

static void BMS_MonitorTaskEntry(void *paramter);
static void BMS_MonitorBattery(void);
static void BMS_MonitorSysMood(void);

void BMS_MonitorInit(void)
{
	rt_thread_t thread;
	
	rt_thread_mdelay(1000);
	
	thread = rt_thread_create("Monitor",
								BMS_MonitorTaskEntry,
								RT_NULL,
								MONITOR_TASK_STACK_SIZE,	
								MONITOR_TASK_PRIORITY,
								MONITOR_TASK_TIMESLICE);

	if (RT_NULL != thread)
	{
		rt_thread_startup(thread);
	}
}

static void BMS_MonitorTaskEntry(void *paramter)
{
	while (1)
	{
		BMS_MonitorBattery();
		BMS_MonitorSysMood();
		rt_thread_mdelay(MONITOR_TASK_PERIOD);
	}
}

static void BMS_MonitorBattery(void)
{
	CountCellVoltage += MONITOR_TASK_PERIOD;
	if (CountCellVoltage >= UPDATE_CELL_VOLTAGE_CYCLE)
	{
		HAL_MonitorCellvoltage();
		CountCellVoltage = 0;
	}
	
	CountBatVoltage += MONITOR_TASK_PERIOD;
	if (CountBatVoltage >= UPDAYE_BAT_VOLTAGE_CYCLE)
	{
		HAL_MonitorBatteryVoltage();
		CountBatVoltage = 0;
	}
	
	CountCellTemp += MONITOR_TASK_PERIOD;
	if (CountCellTemp >= UPDATE_CELL_TEMP_CYCLE)
	{
		HAL_MonitorTemperature();
		CountCellTemp = 0;
	}
	
	CountBatCurrent += MONITOR_TASK_PERIOD;
	if (CountBatCurrent >= UPDATE_BAT_CURRENT_CYCLE)
	{
		HAL_MonitorBatteryCurrent();
		CountBatCurrent = 0;
	}	
}

static void BMS_MonitorSysMood(void)
{
	static BMS_ModeTypeDef SysModeBackup = BMS_MODE_STANDBY;
	static uint32_t StandbyCount = 0;
	
	if (BMS_GlobalParam.SysMode == BMS_MODE_SLEEP)
	{
		if (BMS_MonitorData.BatteryCurrent >= 0.02 || BMS_MonitorData.BatteryCurrent <= -0.02)
		{
			BMS_GlobalParam.SysMode = BMS_MODE_STANDBY;
			LOG_I("Wake Up");
		}
		
		return;
	}
	
	if (BMS_MonitorData.BatteryCurrent <= 0.02 && BMS_MonitorData.BatteryCurrent >= -0.02)
	{
		BMS_GlobalParam.SysMode = BMS_MODE_STANDBY;
		
		if (StandbyCount > BMS_ENTRY_SLEEP_TIME * 60000)
		{
			StandbyCount = 0;
			BMS_GlobalParam.SysMode = BMS_MODE_SLEEP;
			LOG_I("Entry Sleep Mode");
		}
		else
		{
			StandbyCount += MONITOR_TASK_PERIOD;
		}
		
		if (SysModeBackup != BMS_MODE_STANDBY)
		{
			SysModeBackup = BMS_MODE_STANDBY;
			LOG_I("Entry Standby Mode");
		}
	}
	
	else if (BMS_MonitorData.BatteryCurrent > 0.02)
	{
		StandbyCount = 0;
		BMS_GlobalParam.SysMode = BMS_MODE_CHARGE;
		
		if (SysModeBackup != BMS_MODE_CHARGE)
		{
			SysModeBackup = BMS_MODE_CHARGE;
			LOG_I("Entry Charge Mode");
		}
	}
	
	else if (BMS_MonitorData.BatteryCurrent < -0.02)
	{
		StandbyCount = 0;
		BMS_GlobalParam.SysMode = BMS_MODE_DISCHARGE;
		
		if (SysModeBackup != BMS_MODE_DISCHARGE)
		{
			SysModeBackup = BMS_MODE_DISCHARGE;
			LOG_I("Entry Discharge Mode");
		}
	}
}


